package cn.edu.lingnan.service.impl;

import cn.edu.lingnan.mapper.QuestionStoreMapper;
import cn.edu.lingnan.service.QuestionStoreService;
import cn.edu.lingnan.service.QuestionsService;
import cn.edu.lingnan.user.dtos.ListStoresDto;
import cn.edu.lingnan.user.dtos.QuestionStoreDTO;
import cn.edu.lingnan.user.pojos.PageBean;
import cn.edu.lingnan.user.pojos.QuestionStore;
import cn.edu.lingnan.user.pojos.QuestionStoreType;
import cn.edu.lingnan.user.vos.QuestionStoreVO;
import cn.edu.lingnan.user.vos.QuestionWithOptionsVO;
import cn.edu.lingnan.utils.AliOSSUtils;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class QuestionStoreServiceImpl implements QuestionStoreService {

    @Autowired
    private QuestionStoreMapper questionStoreMapper;

    @Autowired
    private AliOSSUtils aliOSSUtils;

    @Autowired
    private QuestionsService questionsService;

    @Autowired
    private StringRedisTemplate redisTemplate;



    @Override
    public PageBean getStoresByUserId(ListStoresDto listStoresDto) {
        // 1. 生成唯一缓存键（包含所有查询条件）
        String cacheKey = generateCacheKey(listStoresDto);

        // 2. 检查缓存是否存在
        String cachedPage = redisTemplate.opsForValue().get(cacheKey);
        if (StringUtils.hasText(cachedPage)) {
            return JSON.parseObject(cachedPage, PageBean.class);
        }

        // 3. 缓存未命中时查询数据库
        PageHelper.startPage(listStoresDto.getPage(), listStoresDto.getSize());
        Page<QuestionStore> stores = questionStoreMapper.selectStoresByUserId(listStoresDto);
        PageBean result = new PageBean(stores.getTotal(), stores.getResult());

        // 4. 写入缓存并设置随机过期时间（防止雪崩）
        redisTemplate.opsForValue().set(
                cacheKey,
                JSON.toJSONString(result),
                60 + new Random().nextInt(60), // 基础60秒 + 随机60秒
                TimeUnit.SECONDS
        );



        return result;
    }

    // 生成包含所有查询条件的缓存键
    private String generateCacheKey(ListStoresDto dto) {
        String paramsHash = DigestUtils.md5DigestAsHex(
                String.format("userId=%d&name=%s&type=%d&page=%d&size=%d",
                        dto.getUserId(),
                        dto.getStoreName() != null ? dto.getStoreName() : "",
                        dto.getStoreTypeId() != null ? dto.getStoreTypeId() : -1,
                        dto.getPage(),
                        dto.getSize()
                ).getBytes()
        );
        return "stores:query:" + paramsHash;
    }

    // 数据变更时清除相关缓存（需在更新/删除方法中调用）
    public void evictStoreCache() {
        // 模糊删除所有包含该店铺特征的缓存
        Set<String> keys = redisTemplate.keys("stores:query:*");
        if (keys != null && !keys.isEmpty()) {
            redisTemplate.delete(keys);
        }
    }

    @Override
    public boolean addStore(QuestionStoreDTO dto) {
        evictStoreCache();
        return questionStoreMapper.insertQuestionStore(dto) > 0;
    }

    @Override
    public boolean updateStore(QuestionStore store) {
        evictStoreCache();
        return questionStoreMapper.updateQuestionStore(store) > 0;
    }

    @Override
    @Transactional
    public Integer deleteStore(Integer storeId) {
        evictStoreCache();
        //删除题库图片
        QuestionStore questionStore=questionStoreMapper.getStoreById(storeId);
        if(questionStore.getImageUrl()!=null){
             aliOSSUtils.delete(questionStore.getImageUrl());
        }
        //查询题库是否有题目
        Integer count=questionsService.countQuestionsByStoreId(storeId);
        if(count>0){
            return 0;
        }
        questionStoreMapper.deleteQuestionStore(storeId);
        return 1;
     }

    @Override
    public List<QuestionWithOptionsVO> getQuestionsByStoreId(Integer storeId) {
        return questionStoreMapper.selectQuestionsWithOptions(storeId);
    }

    @Override
    public List<QuestionStoreType> getStoreTypes() {
        return  questionStoreMapper.selectStoreTypes();
    }

    @Override
    public void updateUserQuestionBankImg(Long storeId, String img) {
        evictStoreCache();
        questionStoreMapper.updateUserQuestionBankImg(storeId, img);
    }

    @Override
    public QuestionStore getStoreById(Integer storeId) {
        return questionStoreMapper.getStoreById(storeId);
    }
}
